package com.ktjiaoyu.travelaiagent.agent;

import com.ktjiaoyu.travelaiagent.advisors.TokenCounterAdvisor;
import org.springframework.ai.chat.client.ChatClient;
import org.springframework.ai.chat.model.ChatModel;
import org.springframework.ai.tool.ToolCallback;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import java.util.Map;

import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_CONVERSATION_ID_KEY;
import static org.springframework.ai.chat.client.advisor.AbstractChatMemoryAdvisor.CHAT_MEMORY_RETRIEVE_SIZE_KEY;

@Component
// 每次获取都是新的智能体对象，避免不同用户使用到同一个对象
@Scope("prototype")
public class KtTravelManus extends ToolCallAgent{

    public static final String MANUS_NAME = "科泰旅游大师";

    public KtTravelManus(ToolCallback[] aiTools,
                         ChatModel dashscopeChatModel) {
        // 传入可用工具
        super(aiTools);
        // 设置智能体名称
        this.setName(MANUS_NAME);
        // 设置智能体角色
        String SYSTEM_PROMPT = """  
               你是“%s” ，一个全能型的 AI 助手，旨在解决用户提出的关于旅游的任何任务。你拥有多种可用工具，可随时调用以高效完成复杂指令。
                """.formatted(MANUS_NAME);
        // 设置智能体系统提示
        this.setSystemPrompt(SYSTEM_PROMPT);
        // 设置智能体下一步提示
        resetNextStepPrompt();
        // 初始化客户端
        ChatClient chatClient = ChatClient.builder(dashscopeChatModel)
                // 由于自行维护记忆消息上下文，所以这里不需要创建MessageChatMemoryAdvisor了
                .defaultAdvisors(new TokenCounterAdvisor())
                .build();
        this.setChatClient(chatClient);
    }
    /** 重写修改最大步数 */
    @Override
    public void setMaxSteps(int maxSteps) {
        super.setMaxSteps(maxSteps);
        // 如果修改了最大任务步数，则重置下一步提示词中的步数要求
        resetNextStepPrompt();
    }

    public void resetNextStepPrompt() {
        String NEXT_STEP_PROMPT = """  
                根据用户需求，主动选择最合适的工具或工具组合。
                对于复杂的任务，你可以将问题分解开来，然后分步骤使用不同的工具来解决它。
                你应该尽量在 %d 个步骤内完成任务，否则任务将可能提前结束，当前已经是第 %d 步。
                在使用每种工具之后，要清晰地说明执行结果，并提出下一步的建议。
                如果您想在任何时刻终止这种交互，请使用“终止”工具/函数调用。
                重要的选择工具规则：
                1、图片搜索只能使用searchImage工具，不允许通过searchWeb和scrapeWebContent搜索和爬取
                2、如果需要搜索信息，请使用searchWeb工具，不允许使用scrapeWebContent工具
                3、如果需要爬取信息，请使用scrapeWebContent工具，不允许使用searchWeb工具
                4、如果需要地理位置信息，请使用高德地图相关工具
                5、如果需要图文并茂的PDF，先下载图片，并使用Markdown格式引用相对路径的图片地址，再传递此Markdown内容，使用generatePdf工具生成
                6、如果用户要求提供文件，在最终响应时提供生成文件的下载链接（A标签，新窗口打开），注意！下载链接需要进行拼接
                    假如文件名是：旅行计划.pdf，
                    则生成A标签的href值是：http://localhost:8080/api/%s/旅行计划.pdf
                """.formatted(getMaxSteps(), getCurrentStep(), getChatId());
        // 设置智能体下一步提示
        this.setNextStepPrompt(NEXT_STEP_PROMPT);
    }
}
